/**
 * 文件名称:  TBcOrganServiceImpl.java
 * 文件序号:  序号
 * 内容描述:  文件简单描述，多行换行书写
 * 版权声明:  山东鸿蝶信息技术有限公司
 * 创建用户:  zhangkai
 * 创建日期:  2017/1/17 15:29
 * 修改用户:  无
 * 修改日期:  无
 * 修改说明:  无
 * 文件版本:  V1.0
 * 文件路径:
 */

package com.hongdee.rbac.dept.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hongdee.common.util.ImageUtils;
import com.hongdee.common.util.StringUtil;
import com.hongdee.common.util.TokenUtil;
import com.hongdee.rbac.dept.dao.ITBcOrganDao;
import com.hongdee.rbac.dept.entity.TBcOrgan;
import com.hongdee.rbac.dept.entity.TBcRunBrands;
import com.hongdee.rbac.dept.service.ITBcOrganService;
import com.hongdee.rbac.role.entity.TBcRole;
import com.hongdee.rbac.role.service.ITBcRoleService;
import com.hongdee.rbac.roledata.entity.TBcRoleDataOrg;
import com.hongdee.rbac.roledata.service.ITBcRoleDataService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.From;
import java.io.*;
import java.util.*;

import static com.hongdee.rbac.Constant.COMPANY;
import static com.hongdee.rbac.Constant.DEPT_ROLE;

/**
 * 名  称:TBcOrganServiceImpl
 * 类  型: class
 * 描  述: 用一句话描述类的作用
 * 路  径:com.hongdee.rbac.dept.service.impl
 * 作  者:zhangkai
 * 日  期:2017/1/17 15:29
 */
@Service
public class TBcOrganServiceImpl implements ITBcOrganService {
    private String tabName = "T_BC_ORGAN";
    private String entityName = "TBcOrgan";
    @Autowired
    private ITBcOrganDao bcOrganDao;

    @Autowired
    private ITBcRoleService roleService;

    @Autowired
    private ITBcRoleDataService roleDataService;

    /**
     * 判断选择的节点部门是否在其数据权限部门之下
     *
     * @param uid
     * @param oId
     * @return
     * @throws Exception
     */
    @Override
    public boolean getChildDeptList(String uid, String oId) throws Exception {
        List<String> deptLists = new ArrayList<>();
        //获得其所有数据权限
        List<Map<String,Object>> list=TokenUtil.getDataCompany(uid);
        if (list.size() > 0) {
            for(int i=0;i<list.size();i++){
                Map infoMap=list.get(i);
                deptLists.add(String.valueOf(infoMap.get("id")));
            }
            if (deptLists.contains(oId)) {
                return true;
            }
        } else {
            return TokenUtil.isCompanyAdmin(uid);
        }
        return false;
    }

    private void setRoleDate(String uid) throws Exception {
        StringBuffer dataSql = new StringBuffer();
        dataSql.append(" SELECT " )
                .append("     rd.role_type, ro.org_id, ro.user_id " )
                .append(" FROM" )
                .append("     t_bc_role_data rd," )
                .append("     t_bc_role_user ru," )
                .append("     t_bc_role_data_org ro" )
                .append(" WHERE" )
                .append("     rd.status = '1' AND rd.id = ru.r_id" )
                .append("         AND ru.r_type = 1" )
                .append("         AND ro.role_id = rd.id" )
                .append("         AND ru.u_id = ?" );

        //获取数据权限
        List<Map<String, Object>> dataRes = this.bcOrganDao.list(dataSql.toString(), uid);
        Map<String, String> orgDataMap = new HashMap<>();
        for (Map<String, Object> map : dataRes) {
            if (DEPT_ROLE.equals(String.valueOf(map.get("roleType" )))) {
                orgDataMap.put(String.valueOf(map.get("orgId" )), uid);
            }
        }
        TokenUtil.setRoleDate(uid, orgDataMap);
    }

    /**
     * @param uid
     * @param oId
     * @return
     * @throws Exception
     */
    @Override
    public boolean getChildDeptListByCompany(String uid, String oId) throws Exception {
        List<String> deptLists = new ArrayList<>();
//        deptLists.add(TokenUtil.getCompanyId(uid));
        this.buildDeptChildUp(oId, deptLists);
        Map<String, String> roleDagte = TokenUtil.getRoleDate(uid);
//        if (deptLists.size() > 0) {
//            String companyId = deptLists.get(0);
            for (String key : roleDagte.keySet()) {
                if (key.equals(oId)) {
                    return true;
                }
            }
//        }
//        return false;
//        List<Map<String,Object>> list=TokenUtil.getDataCompany(uid);
//        if (list.size() > 0) {
//            for (int i = 0; i < list.size(); i++) {
//                Map infoMap = list.get(i);
//                deptLists.add(String.valueOf(infoMap.get("id")));
//            }
//            if (deptLists.contains(oId)) {
//                return true;
//            }
//        }
        return false;
    }

    /**
     * 方法名称:info
     * 方法描述: 查询组织详细数据
     * 参数名称: String id 组织 ID
     * 返回内容:
     * 异常说明:
     * 创建用户:
     * 创建时间:
     * 修改用户:
     * 修改时间:
     * 修改内容:
     */
    @Override
    public Map info(String id) throws Exception {
        if (StringUtils.isEmpty(id)) {
            throw new Exception("请选择字典记录" );
        }
        String sql = "select * from " + tabName + " where id = ? ";
        return this.bcOrganDao.info(sql, new Object[]{id});
    }

    /**
     * 方法名称: update
     * 方法描述: 更新组织状态
     * 参数名称: String id 组织主键
     * 参数名称: String status 组织状态
     * 返回内容:
     * 异常说明:
     * 创建用户:
     * 创建时间:
     * 修改用户:
     * 修改时间:
     * 修改内容:
     */
    @Override
    public void update(String id, String status) throws Exception {
        if (StringUtils.isEmpty(id)) {
            throw new Exception("请选择字典记录" );
        }
        String hql = "update " + entityName + " set status = :status where id = :id ";
        Map params = new HashMap();
        params.put("id", id);
        params.put("status", status);
        this.bcOrganDao.update(hql, params);
    }

    /**
     * 方法名称:saveOrUpdate
     * 方法描述: 保存或更新实体组织数据
     * 参数名称: TBcOrgan 组织实体
     * 返回内容:
     * 异常说明:
     * 创建用户:
     * 创建时间:
     * 修改用户:
     * 修改时间:
     * 修改内容:
     */
    @Override
    public TBcOrgan saveOrUpdate(TBcOrgan data) throws Exception {
        //判断公司录音收听地址的基本格式

        if(!StringUtils.isEmpty(data.getCompanyIpAddress())){
            if(!data.getCompanyIpAddress().matches("^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."

                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."

                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."

                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$" )) {
                throw new Exception("公司录音收听地址格式不正确！" );
            }
        }
        return (TBcOrgan) this.bcOrganDao.saveOrUpdate(data);
    }

    /**
     * 兼修/兼营品牌
     * @param data
     * @return
     * @throws Exception
     */
    @Override
    public TBcOrgan save(Map data) throws Exception{

        //判断公司录音收听地址的基本格式
        if(!StringUtils.isEmpty(data.get("companyIpAddress"))){
            if(!data.get("companyIpAddress").toString().matches("^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."

                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."

                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."

                    + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$" )) {
                throw new Exception("公司录音收听地址格式不正确！" );
            }
        }
        //转换成实体类
        TBcOrgan tBcOrgan = this.getEntity(data);
        TBcOrgan tbc =  (TBcOrgan) this.bcOrganDao.saveOrUpdate(tBcOrgan);
        //删除之前的兼营兼修品牌
        this.bcOrganDao.executeSQL("delete from t_bc_run_brands where o_id =?",tbc.getId());
        //如果有兼营兼修就把相应的品牌加入表中
        if("1".equals(tBcOrgan.getRunBrands())){//兼营
            this.insertToRun(data,tbc.getId(),tbc.getoCarBrand());
        }
        if("1".equals(tBcOrgan.getBuildBrands())){//兼修
            this.insertToBuild(data,tbc.getId(),tbc.getoCarBrand());
        }
        return tbc;
    }
    /**
     * 兼营品牌新增
     * @param data
     * @param id
     * @throws Exception
     */
    private void insertToRun(Map data,String id,String oCarBrand) throws Exception{

        List<TBcRunBrands> dataList = new ArrayList<>();
        //经营品牌
        TBcRunBrands tbc = new TBcRunBrands();
        tbc.setType("0");
        tbc.setoId(id);
        tbc.setBrandCode(oCarBrand);
        dataList.add(tbc);

        List<String> list = new ArrayList();
        if(data.get("runBrands")!=null&&!data.get("runBrands").equals("")){
            list = (ArrayList) data.get("runBrands");
        }
        //兼营
        for(String brandCode:list){
            TBcRunBrands tBcRunBrands = new TBcRunBrands();
            tBcRunBrands.setoId(id);
            tBcRunBrands.setBrandCode(brandCode);
            tBcRunBrands.setType("1");
            dataList.add(tBcRunBrands);
        }

        this.bcOrganDao.saveOrUpdateList(dataList);
    }

    /**
     * 兼修品牌新增
     * @param data
     * @param id
     * @throws Exception
     */
    private void insertToBuild(Map data,String id,String oCarBrand) throws Exception{

        List<TBcRunBrands> dataList = new ArrayList<>();
        if(this.bcOrganDao.list("select * from t_bc_run_brands where brand_code=? and o_id =? and type='0'",oCarBrand,id).size()==0){
            //经营品牌
            TBcRunBrands tbc = new TBcRunBrands();
            tbc.setType("0");
            tbc.setoId(id);
            tbc.setBrandCode(oCarBrand);
            dataList.add(tbc);
        }
        List<String> list = new ArrayList();
        if(data.get("buildBrands")!=null&&!data.get("buildBrands").equals("")){
            list = (ArrayList) data.get("buildBrands");
        }
        //兼修
        for(String brandCode:list){
            TBcRunBrands tBcRunBrands = new TBcRunBrands();
            tBcRunBrands.setoId(id);
            tBcRunBrands.setBrandCode(brandCode);
            tBcRunBrands.setType("2");
            dataList.add(tBcRunBrands);
        }
        this.bcOrganDao.saveOrUpdateList(dataList);
    }

    /**
     * 转成实体类
     * @param data
     * @return
     */
    private TBcOrgan getEntity(Map data){

        TBcOrgan tBcOrgan = new TBcOrgan();

        if(!StringUtils.isEmpty(data.get("oCode"))){//组织编码
            tBcOrgan.setoCode(data.get("oCode").toString());
        }
        if(!StringUtils.isEmpty(data.get("oName"))){//组织名称
            tBcOrgan.setoName(data.get("oName").toString());
        }
        if(!StringUtils.isEmpty(data.get("oShortName"))){//组织简称
            tBcOrgan.setoShortName(data.get("oShortName").toString());
        }
        if(!StringUtils.isEmpty(data.get("oArea"))){//组织区域
           tBcOrgan.setoArea(data.get("oArea").toString());
        }
        if(!StringUtils.isEmpty(data.get("oAreaSecond"))){//组织区域
            tBcOrgan.setoAreaSecond(data.get("oAreaSecond").toString());
        }
        if(!StringUtils.isEmpty(data.get("oCarBrand"))){//经营品牌
           tBcOrgan.setoCarBrand(data.get("oCarBrand").toString());
        }
        if(!StringUtils.isEmpty(data.get("oType"))){//组织类型
           tBcOrgan.setoType(data.get("oType").toString());
        }
        if(!StringUtils.isEmpty(data.get("oProvance"))){//省
           tBcOrgan.setoProvance(data.get("oProvance").toString());
        }
        if(!StringUtils.isEmpty(data.get("oCity"))){//市
           tBcOrgan.setoCity(data.get("oCity").toString());
        }
        if(!StringUtils.isEmpty(data.get("oAddress"))){//详细地址
           tBcOrgan.setoAddress(data.get("oAddress").toString());
        }
        if(!StringUtils.isEmpty(data.get("oDispOrder"))){//显示顺序
           tBcOrgan.setoDispOrder(Integer.parseInt(data.get("oDispOrder").toString()));
        }
        if(!StringUtils.isEmpty(data.get("oPId"))){//上组织id
            tBcOrgan.setoPId(data.get("oPId").toString());
        }
        if(!StringUtils.isEmpty(data.get("oPCode"))){//上组织编码
            tBcOrgan.setoPCode(data.get("oPCode").toString());
        }
        if(!StringUtils.isEmpty(data.get("oDesc"))){//描述
            tBcOrgan.setoDesc(data.get("oDesc").toString());
        }
        if(!StringUtils.isEmpty(data.get("status"))){//状态
           tBcOrgan.setStatus(data.get("status").toString());
        }
        if(!StringUtils.isEmpty(data.get("oPhone"))){//电话
           tBcOrgan.setoPhone(data.get("oPhone").toString());
        }
        if(!StringUtils.isEmpty(data.get("companyIpAddress"))){//录音收听地址维系属性
           tBcOrgan.setCompanyIpAddress(data.get("companyIpAddress").toString());
        }
        if(!StringUtils.isEmpty(data.get("longtitude"))){//经度
           tBcOrgan.setLongtitude(data.get("longtitude").toString());
        }
        if(!StringUtils.isEmpty(data.get("latitude"))){//维度
           tBcOrgan.setLatitude(data.get("latitude").toString());
        }
        if(!StringUtils.isEmpty(data.get("pic"))){//图片
           tBcOrgan.setPic(data.get("pic").toString());
        }
        if(!StringUtils.isEmpty(data.get("runBrands"))){//兼营品牌
           tBcOrgan.setRunBrands("1");
        }
        if(!StringUtils.isEmpty(data.get("buildBrands"))){//兼修品牌
            tBcOrgan.setBuildBrands("1");
        }
        if(!StringUtils.isEmpty(data.get("id"))){//id
            tBcOrgan.setId(data.get("id").toString());
        }
        return tBcOrgan;
    }

    /**
     * 查看详情
     * @param id
     * @return
     * @throws Exception
     */
    @Override
    public Map newInfo(String id) throws Exception{

        if(id==null){
            throw new Exception("请选择一条记录");
        }
        Map map = this.bcOrganDao.info("select * from t_bc_organ where id =?",id);

        //兼营
        List<String> ll = new ArrayList();
        if("1".equals(map.get("runBrands"))) {
            List<Map<String, Object>> list1 = this.bcOrganDao.list("select * from t_bc_run_brands where o_id=? and type='1'", id);
            if (list1.size() > 0) {
                for (Map<String, Object> mm : list1) {
                    ll.add(mm.get("brandCode").toString());
                }
            }
            map.put("runBrands", ll);
        }

        //兼修
       List<String> ls = new ArrayList<>();
       if("1".equals(map.get("buildBrands"))){
           List<Map<String,Object>> list2 = this.bcOrganDao.list("select * from t_bc_run_brands where o_id=? and type='2'",id);
           if(list2.size()>0){
               for(Map<String,Object> mm:list2){
                   ls.add(mm.get("brandCode").toString());
               }
           }
         map.put("buildBrands",ls);
       }
        return map;
    }


    public String findBuildDeptId(String opId) throws Exception {
        String sqlStr = "select * from t_bc_organ  where id = ? ";
        Map infoMap=this.bcOrganDao.info(sqlStr, opId);
        //判断 是否为公司如果类型为公司 则直接 返回
        if(infoMap.size()>0){
            if("1".equals(StringUtil.formatEmpty(infoMap.get("oType")))){
                return StringUtil.formatEmpty(infoMap.get("id"));
            }else{
                return findBuildDeptId(StringUtil.formatEmpty(infoMap.get("oPId")));
            }
        }
        return null;
    }

    /**
     * 用户增加部门信息，
     * 将部门同步增加到其数据角色权限对应的角色下
     *
     * @param data
     * @param uid
     * @throws Exception
     */
    @Override
    public void saveRoleDataOrg(TBcOrgan data, String uid) throws Exception {
        //判断uid如果是普通人员
        String cId = findBuildDeptId(data.getoPId());
        saveRoleDateOrgByCompany(data,uid,cId);
    }

    /**
     * 根据登录人的权限不同 生成查询sql
     * @param roleSqlBuf
     * @param deptList
     * @param params
     * @param uid
     * @param cId
     */
    private void deptAndDateorgManageToSql(StringBuffer roleSqlBuf,List<String> deptList,List<String> params,String uid,String cId){
        String companyId = TokenUtil.getCompanyId(uid);
        StringBuffer sql=new StringBuffer();
        //当前登录人与部门所在的公司是否一致，不一致 说明不在同一个公司，并且对该公司有权限
        //查询uid下的数据角色
        sql.append(" SELECT r.id as rId from t_bc_role_data r,t_bc_role_data_org org where r.id=org.role_id " +
                "and org.role_type='0' and org.org_id in( ");
        for(int i=0;i<deptList.size();i++){
            sql.append("?");
            params.add(deptList.get(i));
            if(i<(deptList.size()-1)){
                sql.append(" , ");
            }
        }
        sql.append(" ) group by org.role_id");
        if (cId.equals(companyId)) {
            //一致 说明为非管理员或者说 各店4s店 给自己新增部门
            roleSqlBuf.append(" select * from ( ");
            roleSqlBuf.append(sql.toString());
            roleSqlBuf.append(" ) r, t_bc_role_user u where r.rId=u.r_id and u.u_id=? and u.r_type='1' group by u.r_id");
            params.add(uid);
        }else{
            roleSqlBuf.append(sql.toString());
        }
    }

    /**
     * 解析sql并将新加入的部门 添加进已有的数据角色中
     * 1、超管新建部门，将部门加入到部门所在的公司所有的数据角色中；
     * 2、非超管新建部门，将部门加入到登录人员所在公司、他所拥有的数据角色中;
     * @param data
     * @param uid
     * @param cId
     * @throws Exception
     */
    private void saveRoleDateOrgByCompany(TBcOrgan data,String uid,String cId) throws Exception {
        List<String> deptList=new ArrayList<>();
        if (data.getId() != null) {
            //所有的部门ID
            roleService.buildDeptChild(cId,deptList);
            deptList.add(cId);
            //判断部门是否存在在当前人员的数据角色里，不在的话新增进数据角色
            StringBuffer roleSqlBuf = new StringBuffer();
            List<String> params=new ArrayList<>();
            deptAndDateorgManageToSql(roleSqlBuf,deptList,params,uid,cId);
            List<Map<String, Object>> RoleList = this.bcOrganDao.list(roleSqlBuf.toString(), params.toArray());
            if (RoleList.size() > 0) {
                List<TBcRoleDataOrg> tBcRoleDataOrgList=new ArrayList<>();
                for (Map map : RoleList) {
                    if (map.get("rId") != "" && !StringUtils.isEmpty(map.get("rId"))) {
                        //查询数据角色下有的部门
                        StringBuffer orgSqlBuf = new StringBuffer();
                        orgSqlBuf.append(" select count(1) count from t_bc_role_data_org where role_id = ? and org_id = ? ");
                        List ps = new ArrayList();
                        ps.add(map.get("rId"));
                        ps.add(data.getId());
                        Map temp = this.bcOrganDao.info(orgSqlBuf.toString(), ps.toArray());
                        if (temp.get("count") != "" && !StringUtils.isEmpty(temp.get("count"))) {
                            if (String.valueOf(temp.get("count")).equals("0")) {
                                //新增部门未在权限中，新增数据权限
                                TBcRoleDataOrg tBcRoleDataOrg = new TBcRoleDataOrg();
                                tBcRoleDataOrg.setOrgId(data.getId());
                                tBcRoleDataOrg.setCreateUser(uid);
                                tBcRoleDataOrg.setCreateTime(Calendar.getInstance().getTimeInMillis());
                                tBcRoleDataOrg.setRoleType("0");
                                tBcRoleDataOrg.setRoleId(String.valueOf(map.get("rId")));
                                tBcRoleDataOrgList.add(tBcRoleDataOrg);
                            }
                        }
                    }
                }
                if(tBcRoleDataOrgList.size()>0){
                    bcOrganDao.saveOrUpdateList(tBcRoleDataOrgList);
                }
            }
            //重新赋值Token
            setRoleDate(uid);
        }
    }


    /**
     * 方法名称: page
     * 方法描述: 分页查询变更历史
     * 参数名称: String start 记录起始行数
     * 参数名称: String limit 分页大小
     * 参数名称: String pId 用户选中的组织 ID
     * 参数名称: String searchValue 组织机构列表查询条件
     * 返回内容: 分页数据:
     * 异常说明:
     * 创建用户: 张国凯
     * 创建时间:
     * 修改用户: 张国凯
     * 修改时间:
     * 修改内容:
     */

    @Override
    public Map page(String start, String limit, String pId, String searchValue, String uid) throws Exception {
        StringBuffer sqlstr = new StringBuffer();
        List<String> params = new ArrayList<>();
        sqlstr.append("select * from " + tabName + " where o_p_id = ?" );
        params.add(pId);
        if (!"".equals(searchValue)) {
            String sV = "%" + searchValue + "%";
            sqlstr.append(" and (o_name like ? or o_short_name like ? ) " );
            params.add(sV);
            params.add(sV);

        }
        //2017-05-14 增加按数据角色权限排除没有权限的部门信息
        Map<String, String> roleDataMap = TokenUtil.getRoleDate(uid);
        List<String> keyList = new ArrayList<>();
        keyList.addAll(roleDataMap.keySet());
        sqlstr.append("and id not in ( select id from t_bc_organ where o_type='2' " );
        if (keyList.size() > 0) {
            sqlstr.append("and id not in(" );
            for (int i = 0; i < keyList.size(); i++) {
                sqlstr.append("?" );
                if (i < (keyList.size() - 1)) {
                    sqlstr.append("," );
                }
                params.add(keyList.get(i));
            }
            sqlstr.append(")" );
        }
        sqlstr.append(")" );
        return bcOrganDao.page(sqlstr.toString(), params.toArray(), start, limit);
    }

    @Override
    public List tree(String companyId, String type) throws Exception {

        String sqlStr = "select * from t_bc_organ  where o_p_id = ? ";
        List<Object> param = new ArrayList();
        param.add(companyId);
        if (!StringUtils.isEmpty(type)) {
            sqlStr += " and o_type = ? ";
            param.add(type);
        }
        sqlStr += " order by o_disp_order asc ";

        List<Map<String, Object>> treeP = this.bcOrganDao.list(sqlStr, param.toArray());
        return buildTreeParent(treeP, type);

    }

    /**
     * 公司下的部门
     *
     * @param companyId
     * @param type
     * @return
     * @throws Exception
     */
    @Override
    public List tree1(String companyId, String type) throws Exception {

        String sqlStr = "select * from t_bc_organ  where o_p_id = ? ";
        List<Object> param = new ArrayList();
        param.add(companyId);
        if (!StringUtils.isEmpty(type)) {
            sqlStr += " and o_type = ? ";
            param.add(type);
        }
        sqlStr += " order by o_disp_order asc ";

        List treeP = this.bcOrganDao.list(sqlStr, param.toArray());
        return treeP;

    }

    /**
     * 方法名称: BuildTreeParent
     * 方法描述: 获取当前节点的子节点，并生成树状结点，结合BuildTreeChild使用
     * 参数名称: List<Map<String, Object>> treeP 树节点集合
     * 返回内容: 无
     * 异常说明: 抛出异常Exception
     * 创建用户: MissJin
     * 创建时间: 2017/1/21/16:56
     * 修改用户:
     * 修改时间:
     * 修改内容:
     */
    private List buildTreeParent(List<Map<String, Object>> treeP, String type) throws Exception {
        if (treeP.size() == 0) {
            return treeP;
        }
        String pId;
        int i = 0;
        for (Map map : treeP) {
            for (int j = 0; j < i; j++) {
                System.out.print(" " );
            }
            System.out.println(i);
            pId = String.valueOf(map.get("id" ));
            List<Map<String, Object>> childList = tree(pId, type);
            map.put("child", childList);
            i++;
        }
        return treeP;
    }

    /**
     * @param root 组织根节点 ID
     * @param type 组织类型
     * @return Map
     * @throws Exception 基类异常
     * @desc 查询组织转换字典
     * @author zhangkai
     * @date 2017/2/9
     * @time 13:38
     * @update_user
     * @update_time
     * @update_desc:
     */
    @Override
    public Map convert(String root, String type) throws Exception {

        String sqlStr = "select id,o_name from t_bc_organ where 1 =1 ";
        List<Object> param = new ArrayList();

//        if (!StringUtils.isEmpty(type)) {
//            sqlStr += " and o_type = ? ";
//            param.add(type);
//        }

        List<Map<String, Object>> organList = this.bcOrganDao.list(sqlStr, param.toArray());
        //将 List 转为 Map，id 为 key，名称为 Value
        Map resMap = new HashMap();
        for (Map map : organList) {
            if (null != map.get("id" ) && !StringUtils.isEmpty(map.get("id" ))) {
                resMap.put(map.get("id" ), map.get("oName" ));
            }
        }

        return resMap;
    }

    /**
     * @param companyId 当前组织 ID
     * @param type      查询类型 0 仅有部门，1 加上人员
     * @return List
     * @desc 查询组织机构树
     */
    @Override
    public List orgTree(String companyId, String type, String uid) throws Exception {
        //减少判断次数
        if (DEPT_ROLE.equals(type)) {
            Map<String, String> roleMap = TokenUtil.getRoleDate(uid);
            List<String> list = new ArrayList<>();
            list.addAll(roleMap.keySet());
            return buildOrgChildByRoleData(companyId, "1", list);
        } else {
            return buildUserChild(companyId);
        }
    }

    @Override
    public List orgOrleDataTree(String companyId, String type, String uid) throws Exception {
        //减少判断次数
        if (DEPT_ROLE.equals(type)) {
            return buildOrgChild(companyId);
        } else {
            return buildUserChild(companyId);
        }
    }


    //---------------------------------修改之后---------------------------------------

    /**
     * @param pId 上级资源 ID
     * @return List
     * @throws Exception
     * @desc 拼接选择的资源树
     */
    private List buildOrgChildByRoleData(String pId, String type, List<String> list) throws Exception {
        StringBuffer sqlStr = new StringBuffer();
        List<String> params = new ArrayList<>();
        sqlStr.append("select id,o_name,'dept' as type,o_type from t_bc_organ where o_p_id=?" );
        params.add(pId);
        if ("1".equals(type)) {
            sqlStr.append("and id not in ( select id from t_bc_organ where o_type='2' and id not in('' " );
            for (int i = 0; i < list.size(); i++) {
                sqlStr.append(",?" );
                params.add(list.get(i));
            }
            sqlStr.append("))" );
        }
        List<Map<String, Object>> treeP = this.bcOrganDao.list(sqlStr.toString(), params.toArray());
        return buildOrgParentByRoleData(treeP, list);
    }


    /**
     * @param treeP 节点列表
     * @return List
     * @throws Exception 基类
     * @desc 获取当前节点的子节点，并生成树状结点，结合buildResChild使用
     */
    private List buildOrgParentByRoleData(List<Map<String, Object>> treeP, List<String> list) throws Exception {
        if (treeP.size() == 0) {
            return treeP;
        }
        List<Map<String, Object>> childList;
        for (Map map : treeP) {
            String resId = String.valueOf(map.get("id" ));
            //判断是否为公司一级
            String type = String.valueOf(map.get("oType" ));
            childList = buildOrgChildByRoleData(resId, type, list);
            //存在子节点，增加子节点 返回
            map.put("child", childList);
        }
        return treeP;
    }
    //---------------------------------修改之后---------------------------------------

    /**
     * @param pId 上级资源 ID
     * @return List
     * @throws Exception
     * @desc 拼接选择的资源树
     */
    private List buildOrgChild(String pId) throws Exception {

        String sqlStr = "select id,o_name,'dept' as type from t_bc_organ where o_p_id=?";
        List<Map<String, Object>> treeP = this.bcOrganDao.list(sqlStr, pId);
        return buildOrgParent(treeP);
    }


    /**
     * @param treeP 节点列表
     * @return List
     * @throws Exception 基类
     * @desc 获取当前节点的子节点，并生成树状结点，结合buildResChild使用
     */
    private List buildOrgParent(List<Map<String, Object>> treeP) throws Exception {
        if (treeP.size() == 0) {
            return treeP;
        }
        List<Map<String, Object>> childList;
        for (Map map : treeP) {
            String resId = String.valueOf(map.get("id" ));
            childList = buildOrgChild(resId);
            //存在子节点，增加子节点 返回
            map.put("child", childList);
        }
        return treeP;
    }

    /**
     * @param pId 上级资源 ID
     * @return List
     * @throws Exception
     * @desc 拼接选择的资源树
     */
    private List buildUserChild(String pId) throws Exception {
        String sqlStr = "select id,o_name,'dept' as type from t_bc_organ where o_p_id=?";
        List<Map<String, Object>> treeP = this.bcOrganDao.list(sqlStr, pId);
        return buildUserParent(treeP);
    }

    /**
     * @param treeP 部门列表
     * @return
     * @throws Exception
     * @desc 部门关联用户
     */
    public List buildUserParent(List<Map<String, Object>> treeP) throws Exception {
        if (treeP.size() == 0) {
            return treeP;
        }
        List<Map<String, Object>> childList;
        List<Map<String, Object>> userList;
        List<Map<String, Object>> treeList;
        treeList = new ArrayList();

        for (Map map : treeP) {
            String resId = String.valueOf(map.get("id" ));
            childList = buildUserChild(resId);
            //获取当前部门所分配的用户
            userList = getUserChild(resId);
            if (childList.size() == 0) {
                //没有下级
                if (userList.size() > 0) {
                    //人员充当下级
                    map.put("child", userList);
                    treeList.add(map);
                }
            } else {
                childList.addAll(userList);
                map.put("child", childList);
                treeList.add(map);
            }
        }
        return treeList;

    }

    /**
     * @param pId 组织机构ID
     * @return List
     * @throws Exception
     * @desc 获取部门的用户
     */
    private List<Map<String, Object>> getUserChild(String pId) throws Exception {
        String sqlStr = "select id,u_name as oName,'user' as type from t_bc_user where id<>'0' and  o_id = ? and u_status='1' ";
        List<Map<String, Object>> userList = this.bcOrganDao.list(sqlStr, pId);
        return userList;
    }

    @Override
    public Map<String, Object> findCompanyInfo(String oid) throws Exception {
        //获取用户部门信息
        Map<String, Object> deptInfo = this.bcOrganDao.info("T_BC_ORGAN", "id", oid);
        //获取公司信息
        Map<String, Object> company = new HashMap();
        if (null != deptInfo && COMPANY.equals(String.valueOf(deptInfo.get("oType" )))) {
            company = deptInfo;
        } else {
            Map<String, Object> comTemp = this.bcOrganDao.info("T_BC_ORGAN", "id", deptInfo.get("oPId" ));
            //否则继续上行查找，直到公司信息，
            while (comTemp != comTemp && comTemp.size() > 0 && !COMPANY.equals(String.valueOf(comTemp.get("oType" )))) {
                comTemp = this.bcOrganDao.info("T_BC_ORGAN", "id", comTemp.get("oPId" ));
            }
            company = comTemp;
        }
        return company;
    }

    /**
     * 向上查找部门所在的公司ID
     *
     * @param opId
     * @param deptList
     * @return
     * @throws Exception
     */
    @Override
    public List<Map<String, Object>> buildDeptChildUp(String opId, List<String> deptList) throws Exception {
        String sqlStr = "select * from t_bc_organ  where id = ? ";
        List<Map<String, Object>> child = this.bcOrganDao.list(sqlStr, opId);
        return buildDeptParent(child, deptList);
    }

    /***
     * 公司：1，部门2
     * @param paranet
     * @param deptList
     * @return
     * @throws Exception
     */
    public List<Map<String, Object>> buildDeptParent(List<Map<String, Object>> paranet, List<String> deptList) throws Exception {
        if (paranet.size() == 0) {
            return paranet;
        }
        String pId;
        for (Map<String, Object> temp : paranet) {
            pId = String.valueOf(temp.get("oPId" ));
            String type = String.valueOf(temp.get("oType" ));
            if ("1".equals(type)) {
                List<Map<String, Object>> childList = buildDeptChildUp(pId, deptList);
                temp.put("child", childList);
            } else if ("2".equals(type)) {
                deptList.add(String.valueOf(temp.get("id" )));
                break;
            }
        }
        return paranet;
    }

    @Override
    public String findCompanyId(String oid) throws Exception {
        String sqlStr = "select * from t_bc_organ  where id = ? ";
        List<Map<String, Object>> child = this.bcOrganDao.list(sqlStr, oid);
        return buildDeptParent(child);
    }


    @Override
    public boolean isChildOfCompany(String companyId, String parentId) throws Exception {

        if (companyId.equals(parentId)) {
            return true;}
        Map childMap = new HashMap();
        buildParentNode(parentId, childMap);
        return childMap.containsKey(companyId);
    }

    /***
     * 根据指定的组织查询其所有上级组织
     * @param deptId
     * @return
     * @throws Exception
     */
    @Override
    public Map<String, Object> parentMap(String deptId) throws Exception {
        Map<String, Object> parentMap = new HashMap();
        String sqlStr = "select * from t_bc_organ  where id = ? ";
        Map<String, Object> temp = this.bcOrganDao.info(sqlStr, deptId);
        //非空，非集团，一直向上取
        for (; temp.size() > 0 && temp.get("oPId" ) != null && !temp.get("oPId" ).toString().equals("0" ); ) {
            //记录当前值
            parentMap.put(temp.get("oPId" ).toString(), temp.get("oPId" ).toString());
            temp = this.bcOrganDao.info(sqlStr, temp.get("oPId" ).toString());
        }
        return parentMap;
    }

    /****
     * 构建父级列表
     * @param oId
     * @param childMap
     * @throws Exception
     */
    private void buildParentNode(String oId, Map childMap) throws Exception {
        String sqlStr = "select * from t_bc_organ  where o_p_id = ? ";
        List<Map<String, Object>> list = this.bcOrganDao.list(sqlStr, oId);
        buildChildNode(list, childMap);
    }

    private void buildChildNode(List<Map<String, Object>> oList, Map childMap) throws Exception {
        if (null == oList || oList.size() == 0) {
            return;
        }
        for (Map<String, Object> temp : oList) {
            childMap.put(temp.get("id" ).toString(), temp.get("id" ).toString());
            buildParentNode(temp.get("id" ).toString(), childMap);
        }

    }


    public String buildDeptParent(List<Map<String, Object>> paranet) throws Exception {
        String pId;
        String id = "";
        for (Map<String, Object> temp : paranet) {
            pId = String.valueOf(temp.get("oPId" ));
            String type = String.valueOf(temp.get("oType" ));
            if ("1".equals(type)) {
                findCompanyId(pId);
            } else if ("2".equals(type)) {
                id = String.valueOf(temp.get("id" ));
                break;
            }
        }
        return id;
    }


    /**
     * 获得所有的公司信息
     * @return
     * @throws Exception
     */
    @Override
    public List<Map<String,Object>> getCompanys(String uid,String area,String brand) throws Exception {
        StringBuffer sql = new StringBuffer();
        sql.append("select  id,o_name  from t_bc_organ where id in (''");
        List<Map<String,Object>> companyMaps=TokenUtil.getDataCompany(uid);
        List<String> params=new ArrayList<>();
        for(int i=0;i<companyMaps.size();i++){
            sql.append(",?");
            Map infoMap=companyMaps.get(i);
            String id=String.valueOf(infoMap.get("id"));
            params.add(id);
            if(i<(companyMaps.size()-1)){
                sql.append(" , ");
            }
        }
        sql.append(" ) ");
        if(!"".equals(area)){
            sql.append(" and o_area=? ");
            params.add(area);
        }
        if(!"".equals(brand)){
            sql.append(" and o_car_brand=? ");
            params.add(brand);
        }
        return bcOrganDao.list(sql.toString(),params.toArray());
    }


    /**
     * 根据公司ID 获得部门信息
     * @param pId
     * @return
     * @throws Exception
     */
    @Override
    public List<Map<String,Object>> getCompanyDept(String pId)throws Exception{
        String sql="select * from t_bc_organ where o_p_id=?";
        return bcOrganDao.list(sql,pId);
    }

    /**

     * @Name: 获取公司和公司ID
     * @Author: Liu XiaoLong
     * @Date: 2017/8/29 18:34
     */
    @Override
    public List<Map<String, Object>> getCNameAndCId() throws Exception {
        String sql = "SELECT id,o_name FROM t_bc_organ";
        return bcOrganDao.list(sql);
    }
    /**

     * @Name: 获取品牌名称和值
     * @Author: Liu XiaoLong
     * @Date: 2017/9/8 20:32
     * @Remark:
     */
    @Override
    public List<Map<String, Object>> getOCarBrand() throws Exception {
        String sql = "SELECT b_name label,b_code value FROM t_bc_brand ";
        return bcOrganDao.list(sql);
    }

/**
 * @Name: 图片写入数据库
 * @Author: Liu XiaoLong
 * @Date: 2017/11/1 17:16
 * @Remark:
 */
    @Override
    public void writePic(MultipartFile image,String id) throws Exception {

        FileInputStream fileInputStream = ImageUtils.getFileInputStream(image);
        List params = new ArrayList();
        String sql = "update t_bc_organ set pic = ? where id = ? ";
        params.add(fileInputStream);
        params.add(id);
        bcOrganDao.executeSQL(sql,params.toArray());

    }

    /**
     * @Name: 从数据库取出图片
     * @Author: Liu XiaoLong
     * @Date: 2017/11/2 10:30
     * @Remark:
     */
    @Override
    public byte[] readPic(String uid, String id) throws Exception {
        String sql = "select * from t_bc_organ where id = ? "; //o_disp_order <> '0'
        List params = new ArrayList();
        params.add(id);
        Map map =  bcOrganDao.info(sql,params.toArray());
        List list = bcOrganDao.list(sql,params.toArray());
        System.out.println(list);
        Object pic =  map.get("pic");
        byte[] bytes = (byte[]) pic;
        return bytes;
    }

    /**
     * 兼营品牌+自营品牌下拉列表
     * @param uid
     * @return
     * @throws Exception
     */
    @Override
    public List<Map> comboBrand(String uid) throws Exception{

        List<Map> resList = new ArrayList<Map>();

        if(uid.equals("0")){
            //超级管理员admin
            List<Map<String,Object>> mapList = this.bcOrganDao.list("select * from t_bc_brand where status ='1'");
            for (Map map : mapList) {
                Map temp = new HashMap();
                temp.put("value", map.get("bCode"));
                temp.put("label", map.get("bName"));
                resList.add(temp);
            }
        }else{
            //自营
            Map mm = this.bcOrganDao.info("select o.*,d.b_name from t_bc_organ o " +
                    "inner join t_bc_brand d on d.b_code = o.o_car_brand where o.id =?",TokenUtil.getCompanyId(uid));
            Map m = new HashMap();
            m.put("value", mm.get("oCarBrand"));
            m.put("label", mm.get("bName"));
            resList.add(m);
            if("1".equals(mm.get("runBrands"))){//兼营
                String sql = " select b.* ,d.b_name from t_bc_run_brands b" +
                        " inner join t_bc_brand d on b.brand_code = d.b_code where b.type = '1' and b.o_id=?";
                List params = new ArrayList();
                params.add(TokenUtil.getCompanyId(uid));
                List<Map<String, Object>> mapList = this.bcOrganDao.list(sql,params.toArray());
                for (Map map : mapList) {
                    if(mm.get("oCarBrand").equals(map.get("brandCode"))){//同样的品牌过滤
                       continue;
                    }
                    Map temp = new HashMap();
                    temp.put("value", map.get("brandCode"));
                    temp.put("label", map.get("bName"));
                    resList.add(temp);
                }
            }
        }

        return resList;
    }


    /**
     * 搜索门店信息
     * @param id
     * @param storeArea
     * @param storePArea
     * @return
     * @throws Exception
     */
    @Override
    public List<Map<String,Object>> deptStoreArea(String id,String storeArea,String storePArea,String type) throws Exception {
        if(!"".equals(type)){
            type=" id ";
        }else{
            type=" CONCAT(id,'_',o_name) ";
        }
        String sql="select "+type+" as value,o_name as label from t_bc_organ where o_p_id=?   ";
        List<Object> params=new ArrayList<>();
        params.add(id);
        if(!"".equals(storePArea)){
            sql+=" and o_area=?";
            params.add(storePArea);
        }
        if(!"".equals(storeArea)){
            sql+=" and o_area_second=?";
            params.add(storeArea);
        }
        return this.bcOrganDao.list(sql,params.toArray());
    }

    /**
     * 获取所有门店
     * @param uid
     * @return
     * @throws Exception
     */
    @Override
    public List<Map<String, Object>> AllDeptStore(String uid) throws Exception {
        String sql="SELECT o_name `value`,id `key` FROM t_bc_organ WHERE o_name LIKE '%店' ";
        return this.bcOrganDao.list(sql);
    }
}
